import sun.print.PeekGraphics;

import java.sql.Array;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: mac
 * Date: 2022-10-21
 * Time: 13:05
 */
class MyArray1{
    public Object[] objects = new Object[10];

    public void set(int pos, Object val){
        objects[pos] = val;
    }
    public Object get(int pos){
        return objects[pos];
    }

    public Object[] getObjects() {
        return objects;
    }

    public void setObjects(Object[] objects) {
        this.objects = objects;
    }
}

/**
 * 理论上来说：Object是所有类的父类
 * T未指定边界时，默认为Object
 * @param <T> 此时代表当前是一个泛型类，T：当成是一个占位符
 */
class MyArray<T extends Number>{//泛型的上界，规定其必须是number或者其子类
    //public T[] objects = new Object[10];//ERROR 1.不能实例化泛型类型的数组

    public T[] objects = (T[]) new Object[10];
    public void set(int pos, T val){
        objects[pos] = val;
    }
    public T get(int pos){
        return objects[pos];
    }

    public T[] getArray() {
        return objects;
    }
}

//写一个泛型类，求出数组当中的最大值
class Alg<T extends Comparable<T>> {//特殊的上界

    public T findMax(T[] array) {
        T max = array[0];
        for (int i = 1; i < array.length; i++) {
            //if (max < array[i]){
            if (max.compareTo(array[i]) < 0){
                max = array[i];
            }
        }
        return max;
    }
}
class Alg2{//特殊的上界
    public static <T extends Comparable<T>> T findMax(T[] array) {
        T max = array[0];
        for (int i = 1; i < array.length; i++) {
            //if (max < array[i]){
            if (max.compareTo(array[i]) < 0) {
                max = array[i];
            }
        }
        return max;
    }
}
class Alg3 {
    public static <T> void print(ArrayList<T> list){
        for (T x:
             list) {
            System.out.println(x + " ");
        }
    }

    public static void print2(ArrayList<?> list){
        for (Object x:list
             ) {
            System.out.print(x + " ");
        }
    }
}
class Person {

}
class Student extends Person {

}
public class TestDemo {
    public static void main(String[] args) {
        ArrayList<? super Person> arrayList1 = new ArrayList<Person>();
        //ArrayList<? super Person> arrayList2 = new ArrayList<Student>();

        //ArrayList<? super Person> arrayList2 = new ArrayList<A>();
        arrayList1.add(new Person());
        arrayList1.add(new Student());//添加的元素 是Person或者Person子类

        //作业
        //Person person = arrayList1.get(0);//why??

        Object o = arrayList1.get(0);//只能拿object来接收

    }
    public static void main8(String[] args) {
        ArrayList<Integer> arrayList1 = new ArrayList<>();
        ArrayList<Double> arrayList2 = new ArrayList<>();
        List<? extends Number> list1 = arrayList1;
        List<? extends Number> list2 = arrayList1;
        //list1.add(0, 1);//通配符的上界不适合写入数据
        //此时list可以引用的子类对象很多，编译器无法确定你具体的数据类型，为了安全，编译器不允许你写入数据
        //list1.add(1, 10.9);
        Number o = list1.get(0);//适合读取数据
        //Integer a = list1.get(0);
    }
    public static void main7(String[] args) {
        ArrayList<Integer> list1 = new ArrayList<>();
        list1.add(1);
        list1.add(2);
        Alg3.print(list1);
        Alg3.print2(list1);
    }
    public static void main6(String[] args) {
        Alg<Integer> alg = new Alg<Integer>();
        System.out.println(alg);
        Alg<Integer> alg1 = new Alg<Integer>();
        System.out.println(alg1);
    }
    public static void main5(String[] args) {
        Integer[] array = {1,2,3,4};
        System.out.println(Alg2.<Integer>findMax(array)) ;
    }
    public static void main4(String[] args) {
        Alg<Integer> alg1 = new Alg<>();
        Integer[] array = {1,12,3,4};
        System.out.println(alg1.findMax(array));

        Alg<String>  alg2 = new Alg<>();
        String[] array2 = {"abc", "hello", "cdef"};
        System.out.println(alg2.findMax(array2));
    }
    public static void main3(String[] args) {
        //MyArray<String> myArray = new MyArray<>();不是number的子类报错

        MyArray<Integer> myArray = new MyArray<>();
        MyArray<Number> myArray1 = new MyArray<>();
        myArray1.set(0,10);
        myArray1.set(1,12.5);

        Integer[] ret = myArray.getArray();//报错

        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.add(1);
        arrayList.add(2);
        Object[] ret2 = arrayList.toArray();//这个方法建议拿toArray方法接收
    }
    public static void main2(String[] args) {
        MyArray<Integer> myArray = new MyArray<>();
        myArray.set(0, 1);
        //myArray.set(1,10);//1.自动进行类型检查
        //String str = myArray.get(0);//2.编译器自动进行类型转换
        //System.out.println(str);

        MyArray<Integer> myArray1 = new MyArray<>();
        //MyArray<Int> myArray2 = new MyArray<>(); 简单类型，不能作为泛型类型的参数

        MyArray myArray2 = new MyArray();
        myArray2.set(0,1);
        myArray2.set(1,10);
        int str2 = (Integer)myArray2.get(0);
    }
    public static void main1(String[] args) {
        MyArray1 myArray = new MyArray1();
        myArray.set(0, "hello");
        myArray.set(1,10);
        String str = (String) myArray.get(0);
        System.out.println(str);
    }
}
